package MathTextModeler
{
	import MathText.WordProblem;
	
	import MyDisplayObjects.DraggableImage;
	import MyDisplayObjects.DraggableMC;
	
	import TaskStructure.LogEvent;
	
	import flash.display.DisplayObjectContainer;
	import flash.display.MovieClip;
	import flash.display.Shape;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.text.*;
	import flash.ui.Mouse;
	
	public class DiagramDisplay extends MovieClip
	{
		private var selectedDiagramContainer:DiagramContainer, highlightedDiagramContainer:DiagramContainer, prevSelectedDiagramContainer:DiagramContainer, prevprevSelectedDiagramContainer:DiagramContainer, prevprevprevSelectedDiagramContainer:DiagramContainer;
		private var displayOptionsXML:XML, imagesContextXML:XML;
		private var otherMCs:Array = null; // all other objects, containers, etc.
		private var unitMCs:Array = null; // the unit objects (e.g., marbles)
		private var variableMCs:Array = null; // the variable
		private var textFields:Array = null;
		private var arrows:Array = null;
		private var backgroundMC:DraggableMC = null;
		private var variableUnitMCs:Array = null; // unit objecs placed on the variable
		private var extra_unitMC:DraggableMC;
		private var draggingMC:DraggableMC;
		private var dragging_unitMC:DraggableMC;
		private var draggedfrom_variableMC:DraggableMC;
		private var combineMC:DraggableMC=null, changeMC:DraggableMC=null, compareMC:DraggableMC=null;
		private var curMC:DraggableMC;
		private var curImageType:String;
		private var displayType:String;
		private var WIDTH:Number, HEIGHT:Number;
		private var wordProblem:WordProblem;
		private var includeUsed:Boolean;
		private var placeInCenter:Boolean;
		// accessible
		private var _diagramContainers:Array;
		private var _scale:Number = 1;
		private var _inModelingMode:Boolean = true;
		// getters
		public function get inModelingMode():Boolean{return _inModelingMode;}
		public function get scale():Number{return _scale;}
		public function get diagramContainers():Array{return _diagramContainers;}
		public function get numUnits():uint{if (unitMCs != null){return unitMCs.length} else {return 0;}}
		public function get numOthers():uint{if (otherMCs != null){return otherMCs.length} else {return 0;}}
		public function get numVariables():uint{if (variableMCs != null){return variableMCs.length;} else {return 0;}}
		public function get hasCombine():Boolean{ if (combineMC != null){return true;} else {return false;}}
		public function get hasCompare():Boolean{ if (compareMC != null){return true;} else {return false;}}
		public function get hasChange():Boolean{ if (changeMC != null){return true;} else {return false;}}
		public function getUnitAt(i:uint):DraggableMC{if (unitMCs != null && i < unitMCs.length){return unitMCs[i]} else { return null;}}
		public function getUnitCoordsAt(i:uint):Point{if (unitMCs != null && i < unitMCs.length){return new Point(unitMCs[i].x, unitMCs[i].y);} else { return null;}}
		public function get panelScale():Number{return _scale;}
		public function set panelScale(s:Number):void
		{
			// scale
			this._scale = s
			this.scaleX = s;
			this.scaleY = s;
		}
		
		public function DiagramDisplay(width:Number, height:Number, wordProblem:WordProblem, displayType:String, displayOptionsXML:XML, imagesContextXML:XML, odiagramContainers:Array = null)
		{
			this.WIDTH = width;
			this.HEIGHT = height;
			this.wordProblem = wordProblem;
			this.displayType = displayType;
			this.displayOptionsXML = displayOptionsXML;
			this.imagesContextXML = imagesContextXML;
			this.graphics.lineStyle(width/200, 0x888888);
			this.graphics.beginFill(0xFCFFFC, 1);
			this.graphics.drawRect(0, 0, width, height);
			this.graphics.endFill();
			this._diagramContainers = new Array();
			textFields = new Array();
			arrows = new Array();
			otherMCs = new Array();
			unitMCs = new Array();
			variableMCs = new Array();	
			if (displayOptionsXML.(attribute("showBackground") == "true").length() > 0){
				if (imagesContextXML..display[0].child("background").length() > 0){
					var dmc:DraggableMC = this.addImageToDisplay(imagesContextXML..display[0]..background[0], "background", false);	
					dmc.addEventListener(Event.COMPLETE, handleBackgroundLoaded);
				} else {
					displayByType();
				}
			} else {
				displayByType();
			}	
			
			if (displayOptionsXML.(attribute("placeInCenter") == "true").length() > 0){
				this.placeInCenter = true;
			} else {
				this.placeInCenter = false;
			}
		}
		
		/** mouse enable all */
		public function enableAllMCs():void{
			for (var i:uint=0; i < unitMCs.length; i++){
				unitMCs[i].mouseEnabled = true;
			}
			for (i=0; i < variableMCs.length; i++){
				variableMCs[i].mouseEnabled = true;
			}
			for (i=0; i < otherMCs.length; i++){
				otherMCs[i].mouseEnabled = true;
			}
		}
		
		/** mouse disnable all */
		public function disableAllMCs():void{
			for (var i:uint=0; i < unitMCs.length; i++){
				unitMCs[i].mouseEnabled = false;
			}
			for (i=0; i < variableMCs.length; i++){
				variableMCs[i].mouseEnabled = false;
			}
			for (i=0; i < otherMCs.length; i++){
				otherMCs[i].mouseEnabled = false;
			}
		}
		
		private function handleBackgroundLoaded(event:Event):void {
			event.currentTarget.removeEventListener(Event.COMPLETE, handleBackgroundLoaded);
			displayByType();
		}
		private function displayByType():void{
			if (displayType.toLowerCase() == "combine"){
				displayCombine();
			} else if (displayType.toLowerCase() == "change"){
				displayChange();
			} else if (displayType.toLowerCase() == "compare"){
				displayCompare();
			} 		
		}
		
		public function displayCombine():void{
			if (this.diagramContainers == null || this.diagramContainers.length == 0){
				var diagramContainer:DiagramContainer;
				if (displayOptionsXML.(attribute("showPersistentContainers") == "true").length() > 0){
					diagramContainers.push(new DiagramContainer(WIDTH/2 - WIDTH*1/8, HEIGHT/2 - HEIGHT*1/8, this.placeInCenter, "rect", "none", 0xFFFFFF, .8, WIDTH/100, 0x444444, 1, 0xFFFFFF, .4, WIDTH/100, 0x444444, 1, 0xFFFFFF, .85, WIDTH/100, 0xFFFF44, 1,0xFFFFFF, .85, WIDTH/100, 0x44FF44, 1));
					diagramContainers.push(new DiagramContainer(WIDTH/2 - WIDTH*1/8, HEIGHT/2 - HEIGHT*1/8, this.placeInCenter, "rect", "none", 0xFFFFFF, .8, WIDTH/100, 0x444444, 1, 0xFFFFFF, .4, WIDTH/100, 0x444444, 1, 0xFFFFFF, .85, WIDTH/100, 0xFFFF44, 1, 0xFFFFFF,.85, WIDTH/100, 0x44FF44, 1));
					diagramContainers.push(new DiagramContainer(WIDTH   - WIDTH*1/8, HEIGHT/2 - HEIGHT*1/8, this.placeInCenter, "rect", "none", 0xFFFFFF, .8, WIDTH/100, 0x444444, 1, 0xFFFFFF, .4, WIDTH/100, 0x444444, 1, 0xFFFFFF, .85, WIDTH/100, 0xFFFF44, 1, 0xFFFFFF,.85, WIDTH/100, 0x44FF44, 1));
				} else {
					diagramContainers.push(new DiagramContainer(WIDTH/2 - WIDTH*1/8, HEIGHT/2 - HEIGHT*1/8, this.placeInCenter, "rect", "none", 0xFFFFFF, 0, WIDTH/100, 0x444444, 0, 0xFFFFFF, 0, WIDTH/100, 0x444444, 0, 0xFFFFFF, 0, WIDTH/100, 0xFFFF44, 1, 0xFFFFFF, 0, WIDTH/100, 0x44FF44, 1));
					diagramContainers.push(new DiagramContainer(WIDTH/2 - WIDTH*1/8, HEIGHT/2 - HEIGHT*1/8, this.placeInCenter, "rect", "none", 0xFFFFFF, 0, WIDTH/100, 0x444444, 0, 0xFFFFFF, 0, WIDTH/100, 0x444444, 0, 0xFFFFFF, 0, WIDTH/100, 0xFFFF44, 1, 0xFFFFFF, 0, WIDTH/100, 0x44FF44, 1));
					diagramContainers.push(new DiagramContainer(WIDTH   - WIDTH*1/8, HEIGHT/2 - HEIGHT*1/8, this.placeInCenter, "rect", "none", 0xFFFFFF, 0, WIDTH/100, 0x444444, 0, 0xFFFFFF, 0, WIDTH/100, 0x444444, 0, 0xFFFFFF, 0, WIDTH/100, 0xFFFF44, 1, 0xFFFFFF, 0, WIDTH/100, 0x44FF44, 1));
				}
				this.addChild(diagramContainers[0]); 
				this.addChild(diagramContainers[1]); 
				this.addChild(diagramContainers[2]);
				if (displayOptionsXML.(attribute("showContainerTitles") == "true").length() > 0){
					textFields.push(new TextField()); TextField(textFields[0]).defaultTextFormat = new TextFormat("Arial", 24, 0x444444); this.addChild(TextField(textFields[0]));
					textFields.push(new TextField()); TextField(textFields[1]).defaultTextFormat = new TextFormat("Arial", 24, 0x444444); this.addChild(TextField(textFields[1]));
					textFields.push(new TextField()); TextField(textFields[2]).defaultTextFormat = new TextFormat("Arial", 24, 0x444444); this.addChild(TextField(textFields[2]));
				}
				if (displayOptionsXML.(attribute("showArrows") == "true").length() > 0){
					arrows.push(new Shape()); Shape(arrows[0]).graphics.lineStyle(WIDTH/200,0x000000); Shape(arrows[0]).graphics.beginFill(0x00FF00); Shape(arrows[0]).graphics.lineTo(WIDTH/16, WIDTH/32); Shape(arrows[0]).graphics.lineTo(WIDTH/32, WIDTH/32); Shape(arrows[0]).graphics.lineTo(WIDTH/32, WIDTH/16), Shape(arrows[0]).graphics.lineTo(-WIDTH/32, WIDTH/16); Shape(arrows[0]).graphics.lineTo(-WIDTH/32, WIDTH/32); Shape(arrows[0]).graphics.lineTo(-WIDTH/16, WIDTH/32); Shape(arrows[0]).graphics.lineTo(0, 0); this.addChild(arrows[0]);
					arrows.push(new Shape()); Shape(arrows[1]).graphics.lineStyle(WIDTH/200,0x000000); Shape(arrows[1]).graphics.beginFill(0x00FF00); Shape(arrows[1]).graphics.lineTo(WIDTH/16, WIDTH/32); Shape(arrows[1]).graphics.lineTo(WIDTH/32, WIDTH/32); Shape(arrows[1]).graphics.lineTo(WIDTH/32, WIDTH/16), Shape(arrows[1]).graphics.lineTo(-WIDTH/32, WIDTH/16); Shape(arrows[1]).graphics.lineTo(-WIDTH/32, WIDTH/32); Shape(arrows[1]).graphics.lineTo(-WIDTH/16, WIDTH/32); Shape(arrows[1]).graphics.lineTo(0, 0); this.addChild(arrows[1]);
				}
			} else {
				if (displayOptionsXML.(attribute("showPersistentContainers") == "true").length() > 0){
					DiagramContainer(diagramContainers[0]).initialize(WIDTH/2 - WIDTH*1/8, HEIGHT/2 - HEIGHT*1/8, this.placeInCenter, "rect", "none", 0xFFFFFF, .8, WIDTH/100, 0x444444, 1, 0xFFFFFF, .4, WIDTH/100, 0x444444, 1, 0xFFFFFF, .85, WIDTH/100, 0xFFFF44, 1,0xFFFFFF, .85, WIDTH/100, 0x44FF44, 1);
					DiagramContainer(diagramContainers[1]).initialize(WIDTH/2 - WIDTH*1/8, HEIGHT/2 - HEIGHT*1/8, this.placeInCenter, "rect", "none", 0xFFFFFF, .8, WIDTH/100, 0x444444, 1, 0xFFFFFF, .4, WIDTH/100, 0x444444, 1, 0xFFFFFF, .85, WIDTH/100, 0xFFFF44, 1,0xFFFFFF, .85, WIDTH/100, 0x44FF44, 1);
					DiagramContainer(diagramContainers[2]).initialize(WIDTH   - WIDTH*1/8, HEIGHT/2 - HEIGHT*1/8, this.placeInCenter, "rect", "none", 0xFFFFFF, .8, WIDTH/100, 0x444444, 1, 0xFFFFFF, .4, WIDTH/100, 0x444444, 1, 0xFFFFFF, .85, WIDTH/100, 0xFFFF44, 1, 0xFFFFFF,.85, WIDTH/100, 0x44FF44, 1);
				} else {
					DiagramContainer(diagramContainers[0]).initialize(WIDTH/2 - WIDTH*1/8, HEIGHT/2 - HEIGHT*1/8, this.placeInCenter, "rect", "none", 0xFFFFFF, 0, WIDTH/100, 0x444444, 0, 0xFFFFFF, 0, WIDTH/100, 0x444444, 0, 0xFFFFFF, 0, WIDTH/100, 0xFFFF44, 1, 0xFFFFFF, 0, WIDTH/100, 0x44FF44, 1);
					DiagramContainer(diagramContainers[1]).initialize(WIDTH/2 - WIDTH*1/8, HEIGHT/2 - HEIGHT*1/8, this.placeInCenter, "rect", "none", 0xFFFFFF, 0, WIDTH/100, 0x444444, 0, 0xFFFFFF, 0, WIDTH/100, 0x444444, 0, 0xFFFFFF, 0, WIDTH/100, 0xFFFF44, 1, 0xFFFFFF, 0, WIDTH/100, 0x44FF44, 1);
					DiagramContainer(diagramContainers[2]).initialize(WIDTH   - WIDTH*1/8, HEIGHT/2 - HEIGHT*1/8, this.placeInCenter, "rect", "none", 0xFFFFFF, 0, WIDTH/100, 0x444444, 0, 0xFFFFFF, 0, WIDTH/100, 0x444444, 0, 0xFFFFFF, 0, WIDTH/100, 0xFFFF44, 1, 0xFFFFFF, 0, WIDTH/100, 0x44FF44, 1);
				}
				if (displayOptionsXML.(attribute("showArrows") == "true").length() > 0){
					if (arrows[0].parent == null) this.addChild(arrows[0]);
					if (arrows[1].parent == null) this.addChild(arrows[1]);
				}
			}
			diagramContainers[0].x = WIDTH/16;
			diagramContainers[0].y = HEIGHT/16;
			diagramContainers[0].adjustForLocationChange();
			diagramContainers[1].x = WIDTH/2 + WIDTH/16;
			diagramContainers[1].y = HEIGHT/16;
			diagramContainers[1].adjustForLocationChange();
			diagramContainers[2].x = WIDTH/16;
			diagramContainers[2].y = HEIGHT/2 + HEIGHT/16;	
			diagramContainers[2].adjustForLocationChange();
			if (displayOptionsXML.(attribute("showContainerTitles") == "true").length() > 0){
				TextField(textFields[0]).text = "Part 1"; TextField(textFields[0]).autoSize = "left"; 
				textFields[0].x = diagramContainers[0].x + (diagramContainers[0].width - textFields[0].width)/2;
				textFields[0].y = diagramContainers[0].y+10;
				TextField(textFields[1]).text = "Part 2"; TextField(textFields[1]).autoSize = "left"; 
				textFields[1].x = diagramContainers[1].x + (diagramContainers[1].width - textFields[1].width)/2;
				textFields[1].y = diagramContainers[1].y+10;
				TextField(textFields[2]).text = "Whole"; TextField(textFields[2]).autoSize = "left"; 
				textFields[2].x = diagramContainers[2].x + (diagramContainers[2].width - textFields[2].width)/2;
				textFields[2].y = diagramContainers[2].y+10;
			}
			if (displayOptionsXML.(attribute("showArrows") == "true").length() > 0){
				arrows[0].rotation = 180;
				arrows[0].x = diagramContainers[0].x + (diagramContainers[0].width)/2;
				arrows[0].y = diagramContainers[2].y+10;
				arrows[1].rotation = 180;
				arrows[1].x = diagramContainers[1].x + (diagramContainers[1].width)/2;
				arrows[1].y = diagramContainers[2].y+10;
			}
			
			//place appropriate images in container
			if (displayOptionsXML.(attribute("autoDisplayContainerImages") == "true").length() > 0){
				this.selectedDiagramContainer = diagramContainers[0];
				var dmc:DraggableMC = addImageToDisplay(imagesContextXML..display..combine..subject1[0], "subject1", true); 
				dmc.addEventListener(Event.COMPLETE, handleCombineSubject1Loaded);
			} else {
				this.dispatchEvent(new Event(Event.INIT));
			}
		}
			private function handleCombineSubject1Loaded (event:Event):void{
				event.currentTarget.removeEventListener(Event.COMPLETE, handleCombineSubject1Loaded);
				this.selectedDiagramContainer = diagramContainers[1];
				var dmc:DraggableMC = addImageToDisplay(imagesContextXML..display..combine..subject2[0], "subject2", true); 
				dmc.addEventListener(Event.COMPLETE, handleCombineSubject2Loaded);
			}
			private function handleCombineSubject2Loaded (event:Event):void{
				event.currentTarget.removeEventListener(Event.COMPLETE, handleCombineSubject2Loaded);
				this.selectedDiagramContainer = diagramContainers[2];
				var dmc:DraggableMC = addImageToDisplay(imagesContextXML..display..combine..combined[0], "combined", true); 
				dmc.addEventListener(Event.COMPLETE, handleCombineSubject3Loaded);
			}
			private function handleCombineSubject3Loaded (event:Event):void{
				event.currentTarget.removeEventListener(Event.COMPLETE, handleCombineSubject3Loaded);
				this.selectedDiagramContainer = null;
				this.dispatchEvent(new Event(Event.INIT));
			}
		
		public function displayChange():void{
			if (this.diagramContainers == null || this.diagramContainers.length == 0){
				var diagramContainer:DiagramContainer 
				if (displayOptionsXML.(attribute("showPersistentContainers") == "true").length() > 0){
					diagramContainers.push(new DiagramContainer(WIDTH/3 - WIDTH*1/16, HEIGHT *3/4, this.placeInCenter, "rect", "none", 0xFFFFFF, .8, WIDTH/100, 0x444444, 1, 0xFFFFFF, .4, WIDTH/100, 0x444444, 1, 0xFFFFFF, .85, WIDTH/100, 0xFFFF44, 1,0xFFFFFF, .85, WIDTH/100, 0x44FF44, 1));
					diagramContainers.push(new DiagramContainer(WIDTH/3 - WIDTH* 1/8, HEIGHT *2/3, this.placeInCenter, "rect", "none", 0xFFFFFF, .8, WIDTH/100, 0x444444, 1, 0xFFFFFF, .4, WIDTH/100, 0x444444, 1, 0xFFFFFF, .85, WIDTH/100, 0xFFFF44, 1, 0xFFFFFF,.85, WIDTH/100, 0x44FF44, 1));
					diagramContainers.push(new DiagramContainer(WIDTH/3 - WIDTH*1/16, HEIGHT *3/4, this.placeInCenter, "rect", "none", 0xFFFFFF, .8, WIDTH/100, 0x444444, 1, 0xFFFFFF, .4, WIDTH/100, 0x444444, 1, 0xFFFFFF, .85, WIDTH/100, 0xFFFF44, 1, 0xFFFFFF,.85, WIDTH/100, 0x44FF44, 1));
				} else {
					diagramContainers.push(new DiagramContainer(WIDTH/3 - WIDTH*1/16, HEIGHT *3/4, this.placeInCenter, "rect", "none", 0xFFFFFF, 0, WIDTH/100, 0x444444, 0, 0xFFFFFF, 0, WIDTH/100, 0x444444, 0, 0xFFFFFF, 0, WIDTH/100, 0xFFFF44, 1, 0xFFFFFF, 0, WIDTH/100, 0x44FF44, 1));
					diagramContainers.push(new DiagramContainer(WIDTH/3 - WIDTH* 1/8, HEIGHT *2/3, this.placeInCenter, "rect", "none", 0xFFFFFF, 0, WIDTH/100, 0x444444, 0, 0xFFFFFF, 0, WIDTH/100, 0x444444, 0, 0xFFFFFF, 0, WIDTH/100, 0xFFFF44, 1, 0xFFFFFF, 0, WIDTH/100, 0x44FF44, 1));
					diagramContainers.push(new DiagramContainer(WIDTH/3 - WIDTH*1/16, HEIGHT *3/4, this.placeInCenter, "rect", "none", 0xFFFFFF, 0, WIDTH/100, 0x444444, 0, 0xFFFFFF, 0, WIDTH/100, 0x444444, 0, 0xFFFFFF, 0, WIDTH/100, 0xFFFF44, 1, 0xFFFFFF, 0, WIDTH/100, 0x44FF44, 1));
				}
				this.addChild(diagramContainers[0]); 
				this.addChild(diagramContainers[1]);
				this.addChild(diagramContainers[2]);
				if (displayOptionsXML.(attribute("showContainerTitles") == "true").length() > 0){
					textFields.push(new TextField()); TextField(textFields[0]).defaultTextFormat = new TextFormat("Arial", 24, 0x444444); this.addChild(TextField(textFields[0]));
					textFields.push(new TextField()); TextField(textFields[1]).defaultTextFormat = new TextFormat("Arial", 24, 0x444444); this.addChild(TextField(textFields[1]));
					textFields.push(new TextField()); TextField(textFields[2]).defaultTextFormat = new TextFormat("Arial", 24, 0x444444); this.addChild(TextField(textFields[2]));
				}
				if (displayOptionsXML.(attribute("showArrows") == "true").length() > 0){
					arrows.push(new Shape()); Shape(arrows[0]).graphics.lineStyle(WIDTH/200,0x000000); Shape(arrows[0]).graphics.beginFill(0x00FF00); Shape(arrows[0]).graphics.lineTo(WIDTH/16, WIDTH/32); Shape(arrows[0]).graphics.lineTo(WIDTH/32, WIDTH/32); Shape(arrows[0]).graphics.lineTo(WIDTH/32, WIDTH/16), Shape(arrows[0]).graphics.lineTo(-WIDTH/32, WIDTH/16); Shape(arrows[0]).graphics.lineTo(-WIDTH/32, WIDTH/32); Shape(arrows[0]).graphics.lineTo(-WIDTH/16, WIDTH/32); Shape(arrows[0]).graphics.lineTo(0, 0); this.addChild(arrows[0]);
					arrows.push(new Shape()); Shape(arrows[1]).graphics.lineStyle(WIDTH/200,0x000000); Shape(arrows[1]).graphics.beginFill(0x00FF00); Shape(arrows[1]).graphics.lineTo(WIDTH/16, WIDTH/32); Shape(arrows[1]).graphics.lineTo(WIDTH/32, WIDTH/32); Shape(arrows[1]).graphics.lineTo(WIDTH/32, WIDTH/16), Shape(arrows[1]).graphics.lineTo(-WIDTH/32, WIDTH/16); Shape(arrows[1]).graphics.lineTo(-WIDTH/32, WIDTH/32); Shape(arrows[1]).graphics.lineTo(-WIDTH/16, WIDTH/32); Shape(arrows[1]).graphics.lineTo(0, 0); this.addChild(arrows[1]);
				}
			} else {
				if (displayOptionsXML.(attribute("showPersistentContainers") == "true").length() > 0){
					DiagramContainer(diagramContainers[0]).initialize(WIDTH/3 - WIDTH*1/16, HEIGHT *3/4, this.placeInCenter, "rect", "none", 0xFFFFFF, .8, WIDTH/100, 0x444444, 1, 0xFFFFFF, .4, WIDTH/100, 0x444444, 1, 0xFFFFFF, .85, WIDTH/100, 0xFFFF44, 1,0xFFFFFF, .85, WIDTH/100, 0x44FF44, 1);
					DiagramContainer(diagramContainers[1]).initialize(WIDTH/3 - WIDTH *1/8, HEIGHT *2/3, this.placeInCenter, "rect", "none", 0xFFFFFF, .8, WIDTH/100, 0x444444, 1, 0xFFFFFF, .4, WIDTH/100, 0x444444, 1, 0xFFFFFF, .85, WIDTH/100, 0xFFFF44, 1, 0xFFFFFF,.85, WIDTH/100, 0x44FF44, 1);
					DiagramContainer(diagramContainers[2]).initialize(WIDTH/3 - WIDTH*1/16, HEIGHT *3/4, this.placeInCenter, "rect", "none", 0xFFFFFF, .8, WIDTH/100, 0x444444, 1, 0xFFFFFF, .4, WIDTH/100, 0x444444, 1, 0xFFFFFF, .85, WIDTH/100, 0xFFFF44, 1,0xFFFFFF, .85, WIDTH/100, 0x44FF44, 1);
				} else {
					DiagramContainer(diagramContainers[0]).initialize(WIDTH/3 - WIDTH*1/16, HEIGHT *3/4, this.placeInCenter, "rect", "none", 0xFFFFFF, 0, WIDTH/100, 0x444444, 0, 0xFFFFFF, 0, WIDTH/100, 0x444444, 0, 0xFFFFFF, 0, WIDTH/100, 0xFFFF44, 1, 0xFFFFFF, 0, WIDTH/100, 0x44FF44, 1);
					DiagramContainer(diagramContainers[1]).initialize(WIDTH/3 - WIDTH *1/8, HEIGHT *2/3, this.placeInCenter, "rect", "none", 0xFFFFFF, 0, WIDTH/100, 0x444444, 0, 0xFFFFFF, 0, WIDTH/100, 0x444444, 0, 0xFFFFFF, 0, WIDTH/100, 0xFFFF44, 1, 0xFFFFFF, 0, WIDTH/100, 0x44FF44, 1);
					DiagramContainer(diagramContainers[2]).initialize(WIDTH/3 - WIDTH*1/16, HEIGHT *3/4, this.placeInCenter, "rect", "none", 0xFFFFFF, 0, WIDTH/100, 0x444444, 0, 0xFFFFFF, 0, WIDTH/100, 0x444444, 0, 0xFFFFFF, 0, WIDTH/100, 0xFFFF44, 1, 0xFFFFFF, 0, WIDTH/100, 0x44FF44, 1);
				}
				if (displayOptionsXML.(attribute("showArrows") == "true").length() > 0){
					if (arrows[0].parent == null) this.addChild(arrows[0]);
					if (arrows[1].parent == null) this.addChild(arrows[1]);
				}
			}
			diagramContainers[0].x = WIDTH/18;
			diagramContainers[0].y = (HEIGHT - diagramContainers[0].height)/2;
			diagramContainers[0].adjustForLocationChange();
			diagramContainers[1].x = (WIDTH - diagramContainers[1].width)/2;
			diagramContainers[1].y = (HEIGHT - diagramContainers[1].height)/2;
			diagramContainers[1].adjustForLocationChange();
			diagramContainers[2].x = WIDTH-WIDTH/18-diagramContainers[2].width;
			diagramContainers[2].y = (HEIGHT - diagramContainers[2].height)/2;
			diagramContainers[2].adjustForLocationChange();
			if (displayOptionsXML.(attribute("showContainerTitles") == "true").length() > 0){
				TextField(textFields[0]).text = "Start"; TextField(textFields[0]).autoSize = "left"; 
				textFields[0].x = diagramContainers[0].x + (diagramContainers[0].width - textFields[0].width)/2;
				textFields[0].y = diagramContainers[0].y+10;
				TextField(textFields[1]).text = "Change"; TextField(textFields[1]).autoSize = "left"; 
				textFields[1].x = diagramContainers[1].x + (diagramContainers[1].width - textFields[1].width)/2;
				textFields[1].y = diagramContainers[1].y+10;
				TextField(textFields[2]).text = "End"; TextField(textFields[2]).autoSize = "left"; 
				textFields[2].x = diagramContainers[2].x + (diagramContainers[2].width - textFields[2].width)/2;
				textFields[2].y = diagramContainers[2].y+10;
			}
			if (displayOptionsXML.(attribute("showArrows") == "true").length() > 0){
				arrows[0].rotation = 90;
				arrows[0].x = diagramContainers[1].x
				arrows[0].y = HEIGHT/2;
				arrows[1].rotation = 90;
				arrows[1].x = diagramContainers[2].x;
				arrows[1].y = HEIGHT/2;
			}
			
			//place appropriate images in container
			if (displayOptionsXML.(attribute("autoDisplayContainerImages") == "true").length() > 0){
				this.selectedDiagramContainer = diagramContainers[0];
				var dmc:DraggableMC = addImageToDisplay(imagesContextXML..display..change..subject1[0], "subject1", true); 
				dmc.addEventListener(Event.COMPLETE, handleChangeSubject1Loaded);
			} else {
				this.dispatchEvent(new Event(Event.INIT));
			}
		}
			private function handleChangeSubject1Loaded (event:Event):void{
				event.currentTarget.removeEventListener(Event.COMPLETE, handleChangeSubject1Loaded);
				this.selectedDiagramContainer = diagramContainers[2];
				var dmc:DraggableMC = addImageToDisplay(imagesContextXML..display..change..subject2[0], "subject2", true); 
				dmc.addEventListener(Event.COMPLETE, handleChangeSubject2Loaded);
			}
			private function handleChangeSubject2Loaded (event:Event):void{
				event.currentTarget.removeEventListener(Event.COMPLETE, handleChangeSubject2Loaded);
				this.selectedDiagramContainer = null;
				this.dispatchEvent(new Event(Event.INIT));
			}
		
		public function displayCompare():void{
			if (this.diagramContainers == null || this.diagramContainers.length == 0){
				var diagramContainer:DiagramContainer 
				if (displayOptionsXML.(attribute("showPersistentContainers") == "true").length() > 0){
					diagramContainers.push(new DiagramContainer(WIDTH*2/3 - WIDTH*1/16, HEIGHT/2 - HEIGHT*1/8, this.placeInCenter, "rect", "center", 0xFFFFFF, .8, WIDTH/100, 0x444444, 1, 0xFFFFFF, .4, WIDTH/100, 0x444444, 1, 0xFFFFFF, .85, WIDTH/100, 0xFFFF44, 1,0xFFFFFF, .85, WIDTH/100, 0x44FF44, 1));
					diagramContainers.push(new DiagramContainer(WIDTH*3/3 - 2*WIDTH*1/16, HEIGHT/2 - HEIGHT*1/8, this.placeInCenter, "rect", "left"  , 0xFFFFFF, .8, WIDTH/100, 0x444444, 1, 0xFFFFFF, .4, WIDTH/100, 0x444444, 1, 0xFFFFFF, .85, WIDTH/100, 0xFFFF44, 1, 0xFFFFFF,.85, WIDTH/100, 0x44FF44, 1, false, false, WIDTH/200, 0x0000FF, 0.5));
					diagramContainers.push(new DiagramContainer(WIDTH*1/3 - WIDTH*1/16, HEIGHT/2 - HEIGHT*1/8, this.placeInCenter, "rect", "right" , 0xFFFFFF, .8, WIDTH/100, 0x444444, 1, 0xFFFFFF, .4, WIDTH/100, 0x444444, 1, 0xFFFFFF, .85, WIDTH/100, 0xFFFF44, 1, 0xFFFFFF,.85, WIDTH/100, 0x44FF44, 1, false, false, WIDTH/200, 0x0000FF, 0.5));
				} else {
					diagramContainers.push(new DiagramContainer(WIDTH*2/3 - WIDTH*1/16, HEIGHT/2 - HEIGHT*1/8, this.placeInCenter, "rect", "center", 0xFFFFFF, 0, WIDTH/100, 0x444444, 0, 0xFFFFFF, 0, WIDTH/100, 0x444444, 0, 0xFFFFFF, 0, WIDTH/100, 0xFFFF44, 1, 0xFFFFFF, 0, WIDTH/100, 0x44FF44, 1));
					diagramContainers.push(new DiagramContainer(WIDTH*3/3 - 2*WIDTH*1/16, HEIGHT/2 - HEIGHT*1/8, this.placeInCenter, "rect", "left"  , 0xFFFFFF, 0, WIDTH/100, 0x444444, 0, 0xFFFFFF, 0, WIDTH/100, 0x444444, 0, 0xFFFFFF, 0, WIDTH/100, 0xFFFF44, 1, 0xFFFFFF, 0, WIDTH/100, 0x44FF44, 1, false, false, WIDTH/200, 0x0000FF, 0.0));
					diagramContainers.push(new DiagramContainer(WIDTH*1/3 - WIDTH*1/16, HEIGHT/2 - HEIGHT*1/8, this.placeInCenter, "rect", "right" , 0xFFFFFF, 0, WIDTH/100, 0x444444, 0, 0xFFFFFF, 0, WIDTH/100, 0x444444, 0, 0xFFFFFF, 0, WIDTH/100, 0xFFFF44, 1, 0xFFFFFF, 0, WIDTH/100, 0x44FF44, 1, false, false, WIDTH/200, 0x0000FF, 0.0));
				}
				this.addChild(diagramContainers[0]); 
				this.addChild(diagramContainers[1]);
				this.addChild(diagramContainers[2]);
				if (displayOptionsXML.(attribute("showContainerTitles") == "true").length() > 0){
					textFields.push(new TextField()); TextField(textFields[0]).defaultTextFormat = new TextFormat("Arial", 24, 0x444444); this.addChild(TextField(textFields[0]));
					textFields.push(new TextField()); TextField(textFields[1]).defaultTextFormat = new TextFormat("Arial", 24, 0x444444); this.addChild(TextField(textFields[1]));
					textFields.push(new TextField()); TextField(textFields[2]).defaultTextFormat = new TextFormat("Arial", 24, 0x444444); this.addChild(TextField(textFields[2]));
				}
				if (displayOptionsXML.(attribute("showArrows") == "true").length() > 0){
					arrows.push(new Shape()); Shape(arrows[0]).graphics.lineStyle(WIDTH/200,0x000000); Shape(arrows[0]).graphics.beginFill(0x00FF00); Shape(arrows[0]).graphics.lineTo(WIDTH/16, WIDTH/32); Shape(arrows[0]).graphics.lineTo(WIDTH/32, WIDTH/32); Shape(arrows[0]).graphics.lineTo(WIDTH/32, WIDTH/16), Shape(arrows[0]).graphics.lineTo(-WIDTH/32, WIDTH/16); Shape(arrows[0]).graphics.lineTo(-WIDTH/32, WIDTH/32); Shape(arrows[0]).graphics.lineTo(-WIDTH/16, WIDTH/32); Shape(arrows[0]).graphics.lineTo(0, 0); 
					arrows.push(new Shape()); Shape(arrows[1]).graphics.lineStyle(WIDTH/200,0x000000); Shape(arrows[1]).graphics.beginFill(0x00FF00); Shape(arrows[1]).graphics.lineTo(WIDTH/16, WIDTH/32); Shape(arrows[1]).graphics.lineTo(WIDTH/32, WIDTH/32); Shape(arrows[1]).graphics.lineTo(WIDTH/32, WIDTH/16), Shape(arrows[1]).graphics.lineTo(-WIDTH/32, WIDTH/16); Shape(arrows[1]).graphics.lineTo(-WIDTH/32, WIDTH/32); Shape(arrows[1]).graphics.lineTo(-WIDTH/16, WIDTH/32); Shape(arrows[1]).graphics.lineTo(0, 0); 
				}
			} else {
				if (displayOptionsXML.(attribute("showPersistentContainers") == "true").length() > 0){
					DiagramContainer(diagramContainers[0]).initialize(WIDTH*2/3 - WIDTH*1/16, HEIGHT/2 - HEIGHT*1/8, this.placeInCenter, "rect", "center", 0xFFFFFF, .8, WIDTH/100, 0x444444, 1, 0xFFFFFF, .4, WIDTH/100, 0x444444, 1, 0xFFFFFF, .85, WIDTH/100, 0xFFFF44, 1,0xFFFFFF, .85, WIDTH/100, 0x44FF44, 1);
					DiagramContainer(diagramContainers[1]).initialize(WIDTH*3/3 - 2*WIDTH*1/16, HEIGHT/2 - HEIGHT*1/8, this.placeInCenter, "rect", "left"  , 0xFFFFFF, .8, WIDTH/100, 0x444444, 1, 0xFFFFFF, .4, WIDTH/100, 0x444444, 1, 0xFFFFFF, .85, WIDTH/100, 0xFFFF44, 1,0xFFFFFF, .85, WIDTH/100, 0x44FF44, 1, false, false, WIDTH/200, 0x0000FF, 0.5);
					DiagramContainer(diagramContainers[2]).initialize(WIDTH*1/3 - WIDTH*1/16, HEIGHT/2 - HEIGHT*1/8, this.placeInCenter, "rect", "right" , 0xFFFFFF, .8, WIDTH/100, 0x444444, 1, 0xFFFFFF, .4, WIDTH/100, 0x444444, 1, 0xFFFFFF, .85, WIDTH/100, 0xFFFF44, 1, 0xFFFFFF,.85, WIDTH/100, 0x44FF44, 1, false, false, WIDTH/200, 0x0000FF, 0.5);
				} else {
					DiagramContainer(diagramContainers[0]).initialize(WIDTH*2/3 - WIDTH*1/16, HEIGHT/2 - HEIGHT*1/8, this.placeInCenter, "rect", "center", 0xFFFFFF, 0, WIDTH/100, 0x444444, 0, 0xFFFFFF, 0, WIDTH/100, 0x444444, 0, 0xFFFFFF, 0, WIDTH/100, 0xFFFF44, 1, 0xFFFFFF, 0, WIDTH/100, 0x44FF44, 1);
					DiagramContainer(diagramContainers[1]).initialize(WIDTH*3/3 - 2*WIDTH*1/16, HEIGHT/2 - HEIGHT*1/8, this.placeInCenter, "rect", "left"  , 0xFFFFFF, 0, WIDTH/100, 0x444444, 0, 0xFFFFFF, 0, WIDTH/100, 0x444444, 0, 0xFFFFFF, 0, WIDTH/100, 0xFFFF44, 1, 0xFFFFFF, 0, WIDTH/100, 0x44FF44, 1, false, false, WIDTH/200, 0x0000FF, 0.0);
					DiagramContainer(diagramContainers[2]).initialize(WIDTH*1/3 - WIDTH*1/16, HEIGHT/2 - HEIGHT*1/8, this.placeInCenter, "rect", "right" , 0xFFFFFF, 0, WIDTH/100, 0x444444, 0, 0xFFFFFF, 0, WIDTH/100, 0x444444, 0, 0xFFFFFF, 0, WIDTH/100, 0xFFFF44, 1, 0xFFFFFF, 0, WIDTH/100, 0x44FF44, 1, false, false, WIDTH/200, 0x0000FF, 0.0);
				}
				if (displayOptionsXML.(attribute("showArrows") == "true").length() > 0){
					if (arrows[0].parent == this) this.removeChild(arrows[0]);
					if (arrows[1].parent == this) this.removeChild(arrows[1]);
				}
			}
			diagramContainers[0].x = WIDTH/16;
			diagramContainers[0].y = HEIGHT/2 + HEIGHT/16;	
			diagramContainers[0].adjustForLocationChange();
			diagramContainers[1].x = WIDTH/16;
			diagramContainers[1].y = HEIGHT/16;
			diagramContainers[1].adjustForLocationChange();
			diagramContainers[2].x = WIDTH*2/3;
			diagramContainers[2].y = HEIGHT/2 + HEIGHT/16;
			diagramContainers[2].adjustForLocationChange();			
			if (displayOptionsXML.(attribute("showContainerTitles") == "true").length() > 0){
				TextField(textFields[0]).text = "Smaller"; TextField(textFields[0]).autoSize = "left"; 
				textFields[0].x = diagramContainers[0].x + (diagramContainers[0].width - textFields[0].width)/2;
				textFields[0].y = diagramContainers[0].y+10;
				TextField(textFields[1]).text = "Bigger"; TextField(textFields[1]).autoSize = "left"; 
				textFields[1].x = diagramContainers[1].x + (diagramContainers[1].width - textFields[1].width)/2;
				textFields[1].y = diagramContainers[1].y+10;
				TextField(textFields[2]).text = "Difference"; TextField(textFields[2]).autoSize = "left"; 
				textFields[2].x = diagramContainers[2].x + (diagramContainers[2].width - textFields[2].width)/2;
				textFields[2].y = diagramContainers[2].y+diagramContainers[2].height-textFields[2].height-10;
				
			}
			//place appropriate images in container
			if (displayOptionsXML.(attribute("autoDisplayContainerImages") == "true").length() > 0){
				this.selectedDiagramContainer = diagramContainers[0];
				var dmc:DraggableMC = addImageToDisplay(imagesContextXML..display..compare..subject1[0], "subject1", true); 
				dmc.addEventListener(Event.COMPLETE, handleCompareSubject1Loaded);
			} else {
				this.dispatchEvent(new Event(Event.INIT));
			}
		}
			private function handleCompareSubject1Loaded (event:Event):void{
				event.currentTarget.removeEventListener(Event.COMPLETE, handleCompareSubject1Loaded);
				this.selectedDiagramContainer = diagramContainers[1];
				var dmc:DraggableMC = addImageToDisplay(imagesContextXML..display..compare.subject2[0], "subject2", true); 
				dmc.addEventListener(Event.COMPLETE, handleCompareSubject2Loaded);
			}
			private function handleCompareSubject2Loaded (event:Event):void{
			event.currentTarget.removeEventListener(Event.COMPLETE, handleCompareSubject2Loaded);
			this.selectedDiagramContainer = null;
			this.dispatchEvent(new Event(Event.INIT));
		}
		
		/** imageName is the name of the image file, imageType is the type of object it is (unit, subject, unknown, etc) */
		public function addImageToDisplay(imageName:String, imageType:String, constrainProportions:Boolean = true):DraggableMC
		{
			if (selectedDiagramContainer == null && imageType != "background") return null;
			curImageType = imageType;
			var BORDERED_WIDTH:Number = this.width - this.width/16;
			if (imageType == "unit")
			{
				curMC = new DraggableImage(BORDERED_WIDTH/20, BORDERED_WIDTH/20, imageName, true, 2);
			} else if (imageType == "subject1" || imageType == "subject2")
			{
				//curMC = new DraggableImage(BORDERED_WIDTH*2/5, BORDERED_WIDTH*2*5/12, imageName);
				curMC = new DraggableImage(selectedDiagramContainer.width, selectedDiagramContainer.height, imageName, true);
			}
			else if (imageType == "combined" || imageType == "changed" || imageType == "compared")
			{
				curMC = new DraggableImage(selectedDiagramContainer.width, selectedDiagramContainer.height, imageName, true);
			}else if (imageType == "variable" || imageType == "unknown")
			{
				curMC = new DraggableImage(BORDERED_WIDTH/5, BORDERED_WIDTH/5, imageName);
			}else if (imageType == "background")
			{
				curMC = new DraggableImage(this.width, this.height, imageName, constrainProportions);
			}else
			{
				curMC = new DraggableImage(BORDERED_WIDTH, BORDERED_WIDTH*2/3, imageName);
			}
			curMC.name = imageType;
			curMC.addEventListener( Event.COMPLETE, _addImageToDisplay);		
			return curMC;
		}
		private function _addImageToDisplay (event:Event):void
		{
			curMC.removeEventListener( Event.COMPLETE, _addImageToDisplay);
			var dmc:DraggableMC = curMC; 
			var imageType:String = curImageType;
			if (imageType == "unit")
			{
				dmc.type = "unit";
				unitMCs.push(dmc);
				this.addChild(dmc);
				// position in selected diagram container
				this.selectedDiagramContainer.placeDraggable(dmc);
				dmc.origin = new Point(dmc.x, dmc.y);		
				dmc.addEventListener(MouseEvent.MOUSE_DOWN, handleDraggingStarted);
			} else if (imageType == "unknown" || imageType == "variable")
			{
				dmc.type = "variable";
				variableMCs.push(dmc);
				if (backgroundMC == null){ this.addChildAt(dmc, diagramContainers.length+otherMCs.length);} 
				else { this.addChildAt(dmc, diagramContainers.length+otherMCs.length+1); }
				this.selectedDiagramContainer.placeDraggable(dmc);
				dmc.origin = new Point(dmc.x, dmc.y);
			} else if (imageType == "background")
			{
				dmc.type = "background";
				backgroundMC = dmc;
				dmc.disabled = true;
				dmc.mouseEnabled = false;
				this.addChildAt(dmc, 0);
				dmc.origin = new Point(dmc.x, dmc.y);
			}else 
			{
				dmc.type = "other";
				otherMCs.push(dmc);
				if (backgroundMC != null) {this.addChildAt(dmc, diagramContainers.length+1);}
				else {this.addChildAt(dmc, diagramContainers.length);}	
				
				if (imageType == "subject1"){ 
					if (displayOptionsXML.(attribute("showLabels") == "true").length() > 0) dmc.addTextLabel(wordProblem.subject1.name, this.width/30, 0x000000); 
				} else if (imageType == "subject2") { 
					if (displayOptionsXML.(attribute("showLabels") == "true").length() > 0) dmc.addTextLabel(wordProblem.subject2.name, this.width/30, 0x000000); 
				} else if (imageType == "compared" || imageType == "combined" || imageType == "changed" || imageType == wordProblem.subject1.getAnyAVerb() || imageType == wordProblem.subject3.name){
					if (imageType == "compared"){ compareMC = dmc; }
					else if (imageType == "changed" || imageType == wordProblem.subject1.getAnyAVerb() ){ changeMC = dmc; }
					else if (imageType == "combined"){ combineMC = dmc; }
					if (displayOptionsXML.(attribute("showLabels") == "true").length() > 0) dmc.addTextLabel(imageType, this.width/25, 0x000000, DraggableMC.FRONT, DraggableMC.CENTER, this.width/40, 0);
					//dmc.addTextLabel(wordProblem.subject2.name, this.width/25, 0x000000, DraggableMC.BACK, DraggableMC.CENTER, this.width/40, 0);
				} 
				this.selectedDiagramContainer.placeDraggable(dmc);
				dmc.origin = new Point(dmc.x, dmc.y);
				dmc.addEventListener(MouseEvent.MOUSE_DOWN, handleDraggingStarted);
			}	
			// change the draggingBounds so we can move across entire display
			if (dmc != backgroundMC) 
			{
				dmc.draggingBounds = new Rectangle(0, 0, parent.width-this.x-dmc.width, this.parent.height-dmc.height);
				this.dispatchEvent(new LogEvent(LogEvent.OBJECT_ADDED, imageType, this.name, dmc.x, dmc.y));
			}
			
		}
		/** Removes everything */
		public function removeAll():void
		{
			var dmc:DraggableMC;
			for (var i:int=unitMCs.length-1; i >= 0; i--)
			{
				dmc = DraggableMC(unitMCs[i]);
				if (inModelingMode){if (dmc.hasEventListener(MouseEvent.MOUSE_DOWN)) dmc.removeEventListener(MouseEvent.MOUSE_DOWN, handleDraggingStarted);}
				else{if (dmc.hasEventListener(MouseEvent.MOUSE_DOWN)) dmc.removeEventListener(MouseEvent.MOUSE_DOWN, handleUnitDraggingStarted);}
				if (dmc.parent == this) this.removeChild(dmc);
				unitMCs.splice(i, 1);
			}
			for (i=variableMCs.length-1; i >= 0; i--)
			{
				dmc = DraggableMC(variableMCs[i]);
				if (inModelingMode){if (dmc.hasEventListener(MouseEvent.MOUSE_DOWN)) dmc.removeEventListener(MouseEvent.MOUSE_DOWN, handleDraggingStarted);}
				else{if (dmc.hasEventListener(MouseEvent.MOUSE_DOWN)) dmc.removeEventListener(MouseEvent.MOUSE_DOWN, handleVariableDraggingStarted);}
				if (dmc.parent == this) this.removeChild(dmc);
				variableMCs.splice(i, 1);
			}
			if (displayOptionsXML.(attribute("autoDisplayContainerImages") == "true").length() == 0){
				for (i=otherMCs.length-1; i >= 0; i--)
				{
					dmc = DraggableMC(otherMCs[i]);
					if (dmc.hasEventListener(MouseEvent.MOUSE_DOWN)) dmc.removeEventListener(MouseEvent.MOUSE_DOWN, handleDraggingStarted);
					if (dmc.parent == this) this.removeChild(dmc);
					otherMCs.splice(i, 1);
				}
			}
			for (i=0; i < this.diagramContainers.length; i++){
				this.diagramContainers[i].removeAll();
			}
		}
		
		public function removeAllMCsOnVariable():void {
			
		}
		
		/** If there is a currently selected container remove all units, variables, and others */
		public function removeAllFromSelectedDiagramContainer():Boolean{
			if (this.selectedDiagramContainer != null){
				selectedDiagramContainer.select = false;
				removeAllFromDiagramContainer(selectedDiagramContainer);
				return true;
			} else {
				return false;
			}
		}
		
		/** If there is a currently previous container remove all units, variables, and others */
		public function removeAllFromPreviouslySelectedDiagramContainer():Boolean{
			if (this.prevSelectedDiagramContainer != null){
				prevSelectedDiagramContainer.select = false;
				removeAllFromDiagramContainer(prevSelectedDiagramContainer);
				return true;
			} else {
				return false;
			}
		}
		
		/** If there is a currently previous previous container remove all units, variables, and others */
		public function removeAllFromPreviouslyPreviouslySelectedDiagramContainer():Boolean{
			if (this.prevprevSelectedDiagramContainer != null){
				prevprevSelectedDiagramContainer.select = false;
				removeAllFromDiagramContainer(prevprevSelectedDiagramContainer);
				return true;
			} else {
				return false;
			}
		}
		
		/** Remove all images from a diagram container */
		public function removeAllFromDiagramContainer(diagramContainer:DiagramContainer):void{
			var dmc:DraggableMC;
			for (var i:int=unitMCs.length-1; i >= 0; i--)
			{
				dmc = DraggableMC(unitMCs[i]);
				if (dmc.associatedDiagramContainer == diagramContainer){
					if (inModelingMode){if (dmc.hasEventListener(MouseEvent.MOUSE_DOWN)) dmc.removeEventListener(MouseEvent.MOUSE_DOWN, handleDraggingStarted);}
					else{if (dmc.hasEventListener(MouseEvent.MOUSE_DOWN)) dmc.removeEventListener(MouseEvent.MOUSE_DOWN, handleUnitDraggingStarted);}
					if (dmc.parent == this){
						this.removeChild(dmc);
					}
					unitMCs.splice(i, 1);
				}
			}
			for (i=variableMCs.length-1; i >= 0; i--)
			{
				dmc = DraggableMC(variableMCs[i]);
				if (dmc.associatedDiagramContainer == diagramContainer){
					if (inModelingMode){if (dmc.hasEventListener(MouseEvent.MOUSE_DOWN)) dmc.removeEventListener(MouseEvent.MOUSE_DOWN, handleDraggingStarted);}
					else{if (dmc.hasEventListener(MouseEvent.MOUSE_DOWN)) dmc.removeEventListener(MouseEvent.MOUSE_DOWN, handleVariableDraggingStarted);}
					if (dmc.parent == this) this.removeChild(dmc);
					diagramContainer.removeUnitMC(variableMCs[i]);
					variableMCs.splice(i, 1);
				}
			}
			if (displayOptionsXML.(attribute("autoDisplayContainerImages") == "true").length() == 0){
				for (i=otherMCs.length-1; i >= 0; i--)
				{
					dmc = DraggableMC(otherMCs[i]);
					if (dmc.associatedDiagramContainer == diagramContainer){
						if (dmc.hasEventListener(MouseEvent.MOUSE_DOWN)) dmc.removeEventListener(MouseEvent.MOUSE_DOWN, handleDraggingStarted);
						if (dmc.parent == this) this.removeChild(dmc);
						diagramContainer.removeOtherMC(otherMCs[i]);
						otherMCs.splice(i, 1);
					}
				}
			}
			diagramContainer.removeAll();	
		}		
		
		/** Removes both a unit and its origin point from arrays */
		public function removeUnitMC (dmc:DraggableMC):Boolean
		{
			for (var i:uint=0; i < unitMCs.length; i++)
			{
				if (unitMCs[i] == dmc)
				{
					if (dmc.hasEventListener(MouseEvent.MOUSE_DOWN)) dmc.removeEventListener(MouseEvent.MOUSE_DOWN, handleDraggingStarted);
					if (dmc.parent == this)this.removeChild(dmc);
					unitMCs.splice(i, 1);
					for (i=0; i < this.diagramContainers.length; i++){
						this.diagramContainers[i].removeUnitMC(dmc);
					}
					return true;
				}
			}
			return false;
		}
		
		/** Removes both a variable and its origin point from arrays */
		public function removeVariableMC (dmc:DraggableMC):Boolean
		{
			for (var i:uint=0; i < variableMCs.length; i++)
			{
				if (variableMCs[i] == dmc)
				{
					if (dmc.hasEventListener(MouseEvent.MOUSE_DOWN)) dmc.removeEventListener(MouseEvent.MOUSE_DOWN, handleDraggingStarted);
					if (dmc.parent == this)this.removeChild(dmc);
					variableMCs.splice(i, 1);
					for (i=0; i < this.diagramContainers.length; i++){
						this.diagramContainers[i].removeVariableMC(dmc);
					}
					return true;
				}
			}
			return false;
		}
		/** Removes both another object and its origin point from arrays */
		public function removeOtherMC (dmc:DraggableMC):Boolean
		{
			if (displayOptionsXML.(attribute("autoDisplayContainerImages") == "true").length() == 0){
				for (var i:uint=0; i < otherMCs.length; i++)
				{
					if (otherMCs[i] == dmc)
					{
						if (dmc.hasEventListener(MouseEvent.MOUSE_DOWN)) dmc.removeEventListener(MouseEvent.MOUSE_DOWN, handleDraggingStarted);
						if (dmc.parent == this)this.removeChild(dmc);
						otherMCs.splice(i, 1);
						for (i=0; i < this.diagramContainers.length; i++){
							this.diagramContainers[i].removeOtherMC(dmc);
						}
						return true;
					}
				}
			}
			return false
		}
		
		////////////////// PROCEDURES FOR SELECTING ONE OF THE DIAGRAM DISPLAY CONTAINERS //////////////////////
		/** Used to initiate a sequence in which a mouse over highlights a diagram container, clicking on it selects it */
		public function selectAContainerStarted (includeUsed:Boolean = true):void
		{
			this.includeUsed = includeUsed;
			//deselectContainer();
							
			disableAllMCs();
			for each (var d:DiagramContainer in this.diagramContainers){
				if (includeUsed || d.used)	d.addEventListener(MouseEvent.MOUSE_OVER, handleMouseOverDiagramContainer);
			}
		}
			private function handleMouseOverDiagramContainer (event:MouseEvent):void{				
				highlightedDiagramContainer = DiagramContainer(event.currentTarget);
				highlightedDiagramContainer.highlight = true;
				highlightedDiagramContainer.addEventListener(MouseEvent.CLICK, handleClickDiagramContainer);
				highlightedDiagramContainer.addEventListener(MouseEvent.MOUSE_OUT, handleMouseOutDiagramContainer);
			}
			private function handleMouseOutDiagramContainer (event:MouseEvent):void{
				event.currentTarget.removeEventListener(MouseEvent.CLICK, handleClickDiagramContainer);
				DiagramContainer(event.currentTarget).highlight = false;
				event.currentTarget.addEventListener(MouseEvent.MOUSE_OVER, handleMouseOverDiagramContainer);
				highlightedDiagramContainer = null;
			}
			private function handleClickDiagramContainer(event:MouseEvent):void{
				DiagramContainer(event.currentTarget).highlight = false;
				selectedDiagramContainer = DiagramContainer(event.currentTarget);
				selectedDiagramContainer.select = true;
				// clear it
				this.removeAllFromDiagramContainer(selectedDiagramContainer);
				// has the diagram we selected been used before, if so create null reference
				if (selectedDiagramContainer == this.prevSelectedDiagramContainer) {
					this.prevSelectedDiagramContainer = null;
				} else if (selectedDiagramContainer == this.prevprevSelectedDiagramContainer) {
					this.prevprevSelectedDiagramContainer = null;
				} else if (selectedDiagramContainer == this.prevprevprevSelectedDiagramContainer) {
					this.prevprevprevSelectedDiagramContainer = null;
				} 
				highlightedDiagramContainer = null;
				enableAllMCs();
				selectAContainerStopped();
				this.dispatchEvent(new Event(Event.SELECT));
			}
		/** We are currently in the process of selecting a diagram container, if back is true it is because we are moving back to a previous sentence,
		 *  in which case we push up previous selected diagram containers (but not to selected).
		 **/
		public function selectAContainerStopped():void 
		{
			for each (var d:DiagramContainer in this.diagramContainers){
				if (d.hasEventListener(MouseEvent.CLICK)) d.removeEventListener(MouseEvent.CLICK, handleClickDiagramContainer);
				if (d.hasEventListener(MouseEvent.MOUSE_OVER)) d.removeEventListener(MouseEvent.MOUSE_OVER, handleMouseOverDiagramContainer);
				if (d.hasEventListener(MouseEvent.MOUSE_OUT)) d.removeEventListener(MouseEvent.MOUSE_OUT, handleMouseOutDiagramContainer);
				d.highlight = false;
			}
		}
		
		/** Sets up references to previous containers as student moves forward */
		public function pushReferencesForward():void{
			// if this is the first time a container may be active, turn off and push down to previous
			this.prevprevprevSelectedDiagramContainer = this.prevprevSelectedDiagramContainer;
			this.prevprevSelectedDiagramContainer = this.prevSelectedDiagramContainer;
			this.prevSelectedDiagramContainer = selectedDiagramContainer;
			if (this.selectedDiagramContainer != null){
				this.selectedDiagramContainer.select = false;
				this.selectedDiagramContainer = null;	
			}
		}
		
		/** Sets up references to previous containers as student moves back */
		public function pushReferencesBack():void{
			this.prevSelectedDiagramContainer = this.prevprevSelectedDiagramContainer;
			this.prevprevSelectedDiagramContainer = this.prevprevprevSelectedDiagramContainer;
			if (this.selectedDiagramContainer != null){
				this.selectedDiagramContainer.select = false;
				this.selectedDiagramContainer = null;	
			}
		}
		
		/*
		public function deselectContainer():Boolean{
			if (selectedDiagramContainer != null){
				if (this.prevSelectedDiagramContainer != null) this.prevprevSelectedDiagramContainer = this.prevSelectedDiagramContainer;
				this.prevSelectedDiagramContainer = selectedDiagramContainer;
				selectedDiagramContainer.select = false;
				this.selectedDiagramContainer = null;
				return true;
			} else {
				return false;
			}
		}
		*/
		public function handleDraggingStarted (event:MouseEvent):void
		{
			draggingMC = DraggableMC(event.currentTarget);
			if (draggingMC.type == "unit")
			{
				this.removeChild(draggingMC);
				this.addChild(draggingMC);
			}
			// add a dragging listener so that we can make sure the object was dragged in bounds
			this.stage.addEventListener(MouseEvent.MOUSE_UP, handleDraggingComplete);
		}
		/** If dragging occurred and stopped out of bounds remove from screen */
		private function handleDraggingComplete (event:MouseEvent):void
		{
			this.stage.removeEventListener(MouseEvent.MOUSE_UP, handleDraggingComplete);
			var dmc:DraggableMC = draggingMC;
			// are we within bounds?
			if (dmc.x < 0 || dmc.x > this.WIDTH - dmc.width || dmc.y < 0 || dmc.y + dmc.height > this.HEIGHT)
			{ // out of bounds			
				
				if (dmc.type == "unit"){ this.removeUnitMC(dmc); }
				else if (dmc.type == "variable" || dmc.type == "unknown"){this.removeVariableMC(dmc);}
				else if (dmc.type == "background"){backgroundMC = null; this.removeChild(dmc);}
				else if (dmc.type == "other"){ this.removeOtherMC(dmc);
					if (dmc == combineMC){ combineMC = null;}
					if (dmc == changeMC){ changeMC = null;}
					if (dmc == compareMC){ compareMC = null;}
				}
				this.dispatchEvent(new LogEvent(LogEvent.OBJECT_REMOVED, dmc.name, this.name, dmc.x, dmc.y));
			} else
			{ // within bounds
				if (dmc.type == "unit" || dmc.type == "variable" || dmc.type == "unknown"){
					// are we overlapping any other objects?
					var overlapping:Boolean = false;
					for each (var odmc:DraggableMC in unitMCs)
					{
						if (dmc != odmc && (dmc.hitTestObject(odmc) || odmc.hitTestObject(dmc))) overlapping = true;
					}
					if (overlapping)
					{
						dmc.x = dmc.origin.x;
						dmc.y = dmc.origin.y;
						dmc.origin = new Point(dmc.x, dmc.y);
					} else
					{
						// see if this object is in a different container
						
						dmc.origin = new Point(dmc.x, dmc.y);
						this.dispatchEvent(new LogEvent(LogEvent.OBJECT_MOVED, dmc.name, this.name, dmc.x, dmc.y));
					}
				} else if (dmc.type == "other"){
					
				}
			}
		}
		////////////////////////////////////////// TRANSITION ///////////////////////////////////////////////////////////////////
		/** switches event listeners */
		public function switchModes ():void{
			if (inModelingMode){
				this.selectAContainerStopped();
				for each (var dmc:DraggableMC in this.unitMCs){
					if (dmc.hasEventListener(MouseEvent.MOUSE_DOWN)) dmc.removeEventListener(MouseEvent.MOUSE_DOWN, handleDraggingStarted);
					dmc.addEventListener(MouseEvent.MOUSE_DOWN, handleUnitDraggingStarted);
				}
				for each (dmc in this.variableMCs){
					if (dmc.hasEventListener(MouseEvent.MOUSE_DOWN)) dmc.removeEventListener(MouseEvent.MOUSE_DOWN, handleDraggingStarted);
					dmc.addEventListener(MouseEvent.MOUSE_DOWN, handleVariableDraggingStarted);
				}
				for each (dmc in this.otherMCs){
					if (dmc.hasEventListener(MouseEvent.MOUSE_DOWN)) dmc.removeEventListener(MouseEvent.MOUSE_DOWN, handleDraggingStarted);
				}
				_inModelingMode = false;
			} else{	
				for each (dmc in this.unitMCs){
					if (dmc.hasEventListener(MouseEvent.MOUSE_DOWN)) dmc.removeEventListener(MouseEvent.MOUSE_DOWN, handleUnitDraggingStarted);
					dmc.addEventListener(MouseEvent.MOUSE_DOWN, handleDraggingStarted);	
					dmc.removeAssociatedSiblings();
				}
				for each (dmc in this.variableMCs){
					if (dmc.hasEventListener(MouseEvent.MOUSE_DOWN)) dmc.removeEventListener(MouseEvent.MOUSE_DOWN, handleVariableDraggingStarted);
					dmc.addEventListener(MouseEvent.MOUSE_DOWN, handleDraggingStarted);
					// for each variable MC get any units within the same area and delete
					var associatedDiagramContainer:DiagramContainer = dmc.associatedDiagramContainer;
					var udmc:DraggableMC;
					for (var i:int= this.unitMCs.length-1; i >= 0; i--){
						udmc = this.unitMCs[i];
						if (udmc.associatedDiagramContainer == associatedDiagramContainer){
							this.unitMCs.splice(i,1);
							udmc.associatedDiagramContainer.removeUnitMC(udmc);
							this.removeChild(udmc);
						}
					}
					dmc.removeAssociatedSiblings();
				}
				for each (dmc in this.otherMCs){
					dmc.addEventListener(MouseEvent.MOUSE_DOWN, handleDraggingStarted);
				}
				removeAllFromPreviouslySelectedDiagramContainer();
				this.pushReferencesBack();
				this.selectAContainerStarted(this.includeUsed);
				_inModelingMode = true;
			}
		}
		
		////////////////////////////////////////// ACTION VIEW   ///////////////////////////////////////////////////////////////////
		/** Unit objects (e.g., marbles) are transitioned from the display to this object */
		public function addUnitMC (dmc:DraggableMC, fromDisplay:DisplayObjectContainer):DraggableMC
		{	
			
			unitMCs.push(dmc);
			dmc.addEventListener(MouseEvent.MOUSE_DOWN, handleUnitDraggingStarted);
			// when adding from an external object, which should be a DiagramContainer, scale object and position
			dmc.scaleX = this._scale;
			dmc.scaleY = this._scale;
			if (fromDisplay != this)
			{
				dmc.x *= this._scale;
				dmc.y *= this._scale;
				dmc.x += fromDisplay.x;
				dmc.y += fromDisplay.y;
			}
			dmc.origin = new Point(dmc.x, dmc.y);
			this.addChild(dmc);
			return dmc;
		}
		
		
		/** Variable object is transitioned from the display thiss to this object */
		public function addVariableMC (dmc:DraggableMC, childDisplay:DisplayObjectContainer):DraggableMC
		{
			variableMCs.push(dmc);
			dmc.addEventListener(MouseEvent.MOUSE_DOWN, handleVariableDraggingStarted);
			dmc.scaleX = this._scale;
			dmc.scaleY = this._scale;
			dmc.x *= this._scale;
			dmc.y *= this._scale;
			dmc.x += childDisplay.x;
			dmc.y += childDisplay.y;
			dmc.origin = new Point(dmc.x, dmc.y);
			this.addChild(dmc);
			dmc.disabled = true;
			return dmc;
		}
		
		/** Return all shopes to the original position */
		public function returnAllToOrigins():void
		{
			for (var i:uint=0; i < unitMCs.length; i++)
			{
				DraggableMC(unitMCs[i]).returnToOrigin();
			}
		}
		
		
		///////////////////////////////////// DRAGGING OBJECTS AROUND SCREEN - I.E., THE OBJECTIVE OF THIS OBJECT ///////////////////
		//////////////// POSSIBILITIES
		/////// 1) Starts at a unit object, ends at a different unit object
		/////// 2) Starts at a unit object, ends at a variable object
		/////// 3) Starts at a unit object, ends on neither
		/////// 4) Starts at a variable object, ends at a unit object
		/////// 5) Starts at a variable object, ends at a different variable object
		/////// 6) Starts at a variable object, ends on neither	
		/** When a user clicks directly on a variable create a new unitMC that will be dragged to be matched.  If successfully matched place at location near variable
		 */
		public function handleVariableDraggingStarted (event:MouseEvent):void
		{
			// create a new unitMC to drag, just duplicate the first one in the array
			if (unitMCs.length > 0) 
			{
				draggedfrom_variableMC = DraggableMC(event.currentTarget);
				dragging_unitMC = DraggableMC(unitMCs[0]).duplicate();
				//make sure that we have loaded the image first
				dragging_unitMC.addEventListener( Event.COMPLETE, _handleVariableDraggingStarted);
				
			}
		}
		private function _handleVariableDraggingStarted (event:Event):void
		{
			dragging_unitMC.removeEventListener( Event.COMPLETE, _handleVariableDraggingStarted);
			extra_unitMC = dragging_unitMC.duplicate(); 
			dragging_unitMC.x = this.mouseX - dragging_unitMC.width/2;
			dragging_unitMC.y = this.mouseY - dragging_unitMC.height/2;
			dragging_unitMC.mouseEnabled = true;
			this.addUnitMC(dragging_unitMC, this);
			dragging_unitMC.startDrag(false, new Rectangle(0, 0, dragging_unitMC.parent.width-dragging_unitMC.width, dragging_unitMC.parent.height-dragging_unitMC.height) );
			this.stage.addEventListener(MouseEvent.MOUSE_UP, handleUnitDraggingComplete);
			Mouse.hide();
		}
		/** When user clicks directly on a unit mc start dragging */
		public function handleUnitDraggingStarted (event:MouseEvent):void
		{
			event.currentTarget.removeEventListener(MouseEvent.MOUSE_DOWN, handleUnitDraggingStarted);
			dragging_unitMC = DraggableMC(event.currentTarget);
			
			if (dragging_unitMC.matchedPair != null) unmatchUnits(dragging_unitMC, dragging_unitMC.matchedPair);
			// create an extra in case we need one for placing in the variable
			extra_unitMC = dragging_unitMC.duplicate(); 
			
			// swap this object to top to ensure that it will pass over everything else
			this.removeChild(dragging_unitMC);
			this.addChild(dragging_unitMC);
			
			this.stage.addEventListener(MouseEvent.MOUSE_UP, handleUnitDraggingComplete);
		}
		/** After the user has dragged a unit object around the screen check to see if he or has successfully touched another unit mc or the variable mc.
		 * Return to original position after completed and tag both objects if successful 
		 */ 
		private function handleUnitDraggingComplete (event:MouseEvent):void
		{
			this.stage.removeEventListener(MouseEvent.MOUSE_UP, handleUnitDraggingComplete);
			
			var hit_unitMC:DraggableMC; 
			var hit_variableMC:DraggableMC; 
			
			// did we release on a unit object, did we release on a variable?
			// go through each object in the unitMCs list and see if these two objects are touching
			for each (var unitMC:DraggableMC in unitMCs)
			{
				if (unitMC != dragging_unitMC && dragging_unitMC.hitTestObject(unitMC))
				{
					hit_unitMC = unitMC; break; 
				}
			}
			// Check to see if we dragged to the variable MC
			for each (var variableMC:DraggableMC in variableMCs)
			{
				if (draggedfrom_variableMC != variableMC && dragging_unitMC.hitTestObject(variableMC))
				{
					hit_variableMC = variableMC; break;
				}
			}
			
			// did we end on a variable, a unit, or neither?
			if (hit_variableMC != null){ // released on a variable object
				// did we start on a variable or a unit
				if (draggedfrom_variableMC != null)
				{ // --VARIABLE TO VARIABLE--
					dragging_unitMC.stopDrag();
					Mouse.show();
					matchVariableUnitToVariable(draggedfrom_variableMC, dragging_unitMC, hit_variableMC, extra_unitMC);
				} else
				{ // --UNIT TO VARIABLE--
					matchUnitToVariable(dragging_unitMC, hit_variableMC, extra_unitMC);
				}				
			} else if (hit_unitMC != null)
			{ // released on a unit object
				// did we start on a variable or a unit
				if (draggedfrom_variableMC != null)
				{ // --VARIABLE TO UNIT--
					dragging_unitMC.stopDrag();
					Mouse.show();
					matchVariableUnitToUnit(draggedfrom_variableMC, dragging_unitMC, hit_unitMC);
				} else
				{ // --UNIT TO UNIT--
					this.matchUnitToUnit(dragging_unitMC, hit_unitMC);
				}	
			} else
			{ // released on nothing
				// --VARIABLE TO NOTHING--
				if (draggedfrom_variableMC != null)
				{ // started from variable
					dragging_unitMC.stopDrag();
					Mouse.show();
					this.returnUnit(dragging_unitMC, draggedfrom_variableMC);
				} else
				{ // --UNIT TO NOTHING--
					this.returnUnit(dragging_unitMC, dragging_unitMC.firstAssociatedSibling);
				}	
			}
			dragging_unitMC.addEventListener(MouseEvent.MOUSE_DOWN, handleUnitDraggingStarted);
			dragging_unitMC = null;
			draggedfrom_variableMC = null;
		}
		
		/////// SUBFUNCTIONS TO DEAL WITH MATCHING-UP OBJECTS
		
		/** Match two units, the first unit should already been unmatched, the second might still be matched */
		private function matchUnitToUnit (sourceMC:DraggableMC, targetMC:DraggableMC):void
		{
			if (targetMC.matchedPair != null)
			{ // matched
				// if there is a partner then there should be borders and we need to drop the pair stuff
				if (targetMC.matchedPair != null) unmatchUnits(targetMC, targetMC.matchedPair);
			}
			returnUnit(sourceMC);
			matchUnits(sourceMC, targetMC);	
			this.dispatchEvent(new LogEvent(LogEvent.OBJECTS_MATCHED, sourceMC.name, getDiagramContainerNameUnderPoint(sourceMC.origin), sourceMC.origin.x, sourceMC.origin.y, targetMC.name, getDiagramContainerNameUnderPoint(targetMC.origin), targetMC.origin.x, targetMC.origin.y));
		}
		/** Match a unitMC to a new unitMC created at the variableMC, targetMC MC is the new one created at the variable */
		private function matchUnitToVariable (sourceMC:DraggableMC, targetvariableMC:DraggableMC, targetMC:DraggableMC):void
		{
			// make sure we were given a new unit to match this one with
			if (targetMC != null)
			{
				targetvariableMC.addAssociatedSibling(targetMC);
				targetMC.addAssociatedSibling(targetvariableMC);
				this.getDiagramContainerUnderPoint(new Point(targetvariableMC.x+targetvariableMC.width/2, targetvariableMC.y+targetvariableMC.height/2)).placeDraggable(targetMC);
				//targetMC.moveSquareFromPoint(new Point(targetvariableMC.x+targetvariableMC.width/2, targetvariableMC.y+targetvariableMC.height/2), targetvariableMC.numAssociatedSiblings, 1.25, scale);
				this.addUnitMC(targetMC, this);					
				returnUnit(sourceMC);
				matchUnits(sourceMC, targetMC);
				this.dispatchEvent(new LogEvent(LogEvent.OBJECTS_MATCHED, sourceMC.name, getDiagramContainerNameUnderPoint(sourceMC.origin), sourceMC.origin.x, sourceMC.origin.y, targetvariableMC.name, getDiagramContainerNameUnderPoint(new Point(targetvariableMC.x, targetvariableMC.y)), targetMC.origin.x, targetMC.origin.y));		
			} 
		}
		/** Match a unitMC that originated at the variable to a new target.  Place the source back at the variable */
		private function matchVariableUnitToUnit (sourcevariableMC:DraggableMC, sourceMC:DraggableMC, targetMC:DraggableMC):void
		{
			sourcevariableMC.addAssociatedSibling(sourceMC);
			sourceMC.addAssociatedSibling(sourcevariableMC);
			this.getDiagramContainerUnderPoint(new Point(sourcevariableMC.x+sourcevariableMC.width/2, sourcevariableMC.y+sourcevariableMC.height/2)).placeDraggable(sourceMC);
			//sourceMC.moveSquareFromPoint(new Point(sourcevariableMC.x+sourcevariableMC.width/2, sourcevariableMC.y+sourcevariableMC.height/2), sourcevariableMC.numAssociatedSiblings, 1.25, scale);
			if (targetMC.matchedPair != null) unmatchUnits(targetMC, targetMC.matchedPair);
			matchUnits(sourceMC, targetMC);	
			this.dispatchEvent(new LogEvent(LogEvent.OBJECTS_MATCHED, sourcevariableMC.name, getDiagramContainerNameUnderPoint(new Point(sourcevariableMC.x, sourcevariableMC.y)), sourceMC.origin.x, sourceMC.origin.y, targetMC.name, getDiagramContainerNameUnderPoint(targetMC.origin), targetMC.origin.x, targetMC.origin.y));
			
		}
		/** Go from a variable to a variable, not sure if this should be used, maybe for extensions */
		private function matchVariableUnitToVariable (sourcevariableMC:DraggableMC, sourceMC:DraggableMC, targetvariableMC:DraggableMC, targetMC:DraggableMC):void 
		{
			targetvariableMC.addAssociatedSibling(targetMC);
			targetMC.addAssociatedSibling(targetvariableMC);
			this.getDiagramContainerUnderPoint(new Point(targetvariableMC.x+targetvariableMC.width/2, targetvariableMC.y+targetvariableMC.height/2)).placeDraggable(targetMC);
			//targetMC.moveSquareFromPoint(new Point(targetvariableMC.x+targetvariableMC.width/2, targetvariableMC.y+targetvariableMC.height/2), targetvariableMC.numAssociatedSiblings, 1.25, scale);
			returnUnit(sourceMC);
			sourcevariableMC.addAssociatedSibling(sourceMC);
			sourceMC.addAssociatedSibling(sourcevariableMC);
			this.getDiagramContainerUnderPoint(new Point(sourcevariableMC.x+sourcevariableMC.width/2, sourcevariableMC.y+sourcevariableMC.height/2)).placeDraggable(sourceMC);
			//sourceMC.moveSquareFromPoint(new Point(sourcevariableMC.x+sourcevariableMC.width/2, sourcevariableMC.y+sourcevariableMC.height/2), sourcevariableMC.numAssociatedSiblings, 1.25, scale);
			this.addUnitMC(targetMC, this);					
			matchUnits(sourceMC, targetMC);
			this.dispatchEvent(new LogEvent(LogEvent.OBJECTS_MATCHED, sourcevariableMC.name, getDiagramContainerNameUnderPoint(new Point(sourcevariableMC.x, sourcevariableMC.y)), sourceMC.origin.x, sourceMC.origin.y, targetvariableMC.name, getDiagramContainerNameUnderPoint(new Point(targetvariableMC.x, targetvariableMC.y)), targetMC.origin.x, targetMC.origin.y));
			
		}
		/** Return the unit to its origin or, if variableMC is not null, remove the unit completely */
		private function returnUnit (sourceMC:DraggableMC, variableMC:DraggableMC = null):void
		{
			
			if (variableMC != null)
			{ // this came from a variable, remove completely
				this.removeChild(sourceMC);
			} else
			{ // this came from a previous unit, return to original space
				// return dragging_unitMC to its original space
				sourceMC.returnToOrigin();				
			}
		}
		private function matchUnits (sourceMC:DraggableMC, targetMC:DraggableMC):void
		{
			// Figure out what color to assign to this tagged border
			var borderColor:uint;
			var diagramContainerIndexFrom:int, diagramContainerIndexTo:int; 
			diagramContainerIndexFrom = this.getDiagramContainerIndexUnderPoint(sourceMC.origin);
			diagramContainerIndexTo = this.getDiagramContainerIndexUnderPoint(targetMC.origin);
			if (diagramContainerIndexFrom == 0 && diagramContainerIndexTo == 1 || diagramContainerIndexFrom == 1 && diagramContainerIndexTo == 0)
			{
				borderColor = 0x0000FF;
			} else if (diagramContainerIndexFrom == 1 && diagramContainerIndexTo == 2 || diagramContainerIndexFrom == 2 && diagramContainerIndexTo == 1)
			{
				borderColor = 0xFF00FF;
			} else if (diagramContainerIndexFrom == 0 && diagramContainerIndexTo == 2 || diagramContainerIndexFrom == 2 && diagramContainerIndexTo == 0)
			{
				borderColor = 0xFF0000;
			}
			sourceMC.drawBorder(sourceMC.width/10, borderColor, 1);
			targetMC.drawBorder(sourceMC.width/10, borderColor, 1);
			sourceMC.matchedPair = targetMC;
			targetMC.matchedPair = sourceMC;
			updateNumberModelOfDraggableMC (sourceMC, 1);
			updateNumberModelOfDraggableMC (targetMC, 1);
			
		}
		/** Given two matched units removes the match.  If the target is on a variable, then remove completely. */
		private function unmatchUnits (sourceMC:DraggableMC, targetMC:DraggableMC):Boolean
		{
			if (sourceMC.matchedPair == targetMC)
			{
				this.dispatchEvent(new LogEvent(LogEvent.OBJECTS_UNMATCHED, sourceMC.name, getDiagramContainerNameUnderPoint(sourceMC.origin), sourceMC.origin.x, sourceMC.origin.y, targetMC.name, getDiagramContainerNameUnderPoint(targetMC.origin), targetMC.origin.x, targetMC.origin.y));
				sourceMC.drawBorder(0);
				targetMC.drawBorder(0);
				sourceMC.matchedPair = null;
				targetMC.matchedPair = null;
				// go through all variableMCs, look to see if either the target or source is associated, if so un-associate and remove completely
				for each (var variableMC:DraggableMC in variableMCs)
				{
					if (variableMC.indexOfAssociatedSibling(targetMC) > -1)
					{
						variableMC.removeAssociatedSibling(targetMC);
						this.removeChild(targetMC);
						break;
					}
				}
				updateNumberModelOfDraggableMC (sourceMC, -1);
				updateNumberModelOfDraggableMC (targetMC, -1);
				
				return true;
			} else
			{
				
				return false;
			}
		}
		/** Gives the the diagramContainer (stored in an array) under the given point. -1 means not on sentence display */
		private function getDiagramContainerUnderPoint(p:Point):DiagramContainer
		{
			for (var i:uint=0; i < diagramContainers.length; i++)
			{
				if (p.x >= diagramContainers[i].x && p.x <= diagramContainers[i].x+diagramContainers[i].width && p.y >= diagramContainers[i].y && p.y <= diagramContainers[i].y+diagramContainers[i].height)
				{
					return diagramContainers[i];
				}					
			}
			return null;
		}
		/** Gives the index of the diagramContainer (stored in an array) under the given point. -1 means not on sentence display */
		private function getDiagramContainerIndexUnderPoint(p:Point):int
		{
			for (var i:uint=0; i < diagramContainers.length; i++)
			{
				if (p.x >= diagramContainers[i].x && p.x <= diagramContainers[i].x+diagramContainers[i].width && p.y >= diagramContainers[i].y && p.y <= diagramContainers[i].y+diagramContainers[i].height)
				{
					return i;
				}					
			}
			return -1;
		}
		/** Gives the index of the diagramContainer (stored in an array) under the given point. -1 means not on sentence display */
		private function getDiagramContainerNameUnderPoint(p:Point):String
		{
			for (var i:uint=0; i < diagramContainers.length; i++)
			{
				if (p.x >= diagramContainers[i].x && p.x <= diagramContainers[i].x+diagramContainers[i].width && p.y >= diagramContainers[i].y && p.y <= diagramContainers[i].y+diagramContainers[i].height)
				{
					if (i==0) { return "left";}
					else if (i==1) { return "middle";}
					else if (i==2) { return "right";}
				}					
			}
			return "";
		}
		
		////////////////////////////////////////////// WORK WITH NUMBERS //////////////////////////////////////////////////
		public function updateNumberModelOfDraggableMC(dmc:DraggableMC, dx:Number):void
		{
			var index:int = getDiagramContainerIndexUnderPoint(new Point(dmc.x, dmc.y));
			if (index == 0)
			{
				ActionModeler(parent).numberModel.increaseLeft(dx);
			} else if (index == 1)
			{
				ActionModeler(parent).numberModel.increaseMiddle(dx);
			} else if (index == 2)
			{
				ActionModeler(parent).numberModel.increaseRight(dx);
			} 
		}
	}
}